package body v8.Class_V8 is

   -----------------
   -- Get_Version --
   -----------------

   function Get_Version return String is
      function Invoke return chars_ptr;
      pragma Import (CPP, Invoke, "_ZN2v82V810GetVersionEv");
   begin
      return C.Strings.Value (Invoke);
   end Get_Version;
   pragma Inline (Get_Version);

   -----------------------------
   -- Set_Fatal_Error_Handler --
   -----------------------------

   type C_Fatal_Error_Callback is access procedure
     (Location : chars_ptr;
      Message  : chars_ptr);
   pragma Convention (C, C_Fatal_Error_Callback);

   Current_Fatal_Error_Callback : Fatal_Error_Callback := null;

   procedure Fatal_Error_Callback_Proxy
     (Location : C.Strings.chars_ptr;
      Message  : C.Strings.chars_ptr);
   pragma Convention (C, Fatal_Error_Callback_Proxy);
   -- v8 internal require C_Fatal_Error_Callback as handler,
   -- so we use a proxy to invoke ada Fatal_Error_Callback


   procedure Fatal_Error_Callback_Proxy
     (Location : C.Strings.chars_ptr;
      Message  : C.Strings.chars_ptr)is
   begin
      if Current_Fatal_Error_Callback /= null then
         Current_Fatal_Error_Callback (C.Strings.Value (Location), C.Strings.Value (Message));
      end if;
   end Fatal_Error_Callback_Proxy;

   procedure Set_Fatal_Error_Handler (callback : Fatal_Error_Callback) is
      procedure Invoke (that : C_Fatal_Error_Callback);
      pragma Import (CPP, Invoke, "_ZN2v82V820SetFatalErrorHandlerEPFvPKcS2_E");
   begin
      if callback /= null then
         Current_Fatal_Error_Callback := callback;
         Invoke (Fatal_Error_Callback_Proxy'Access);
      else
         Current_Fatal_Error_Callback := null;
         Invoke (null);
      end if;
   end Set_Fatal_Error_Handler;

   --------------------------
   -- Set_Counter_Function --
   --------------------------

   type C_Counter_Lookup_Callback is access function
     (name : chars_ptr
     ) return access int;
   pragma Convention (C, C_Counter_Lookup_Callback);

   Current_Counter_Lookup_Callback : Counter_Lookup_Callback := null;

   function Counter_Lookup_Callback_Proxy
     (name : chars_ptr
     ) return access int;
   pragma Convention (C, Counter_Lookup_Callback_Proxy);
   -- v8 internal require C_Counter_Lookup_Callback as callback,
   -- so we use proxy to invoke ada Counter_Lookup_Callback

   function Counter_Lookup_Callback_Proxy
     (name : chars_ptr
     ) return access int
   is
   begin
      if Current_Counter_Lookup_Callback /= null then
         return Current_Counter_Lookup_Callback (C.Strings.Value (name));
      else
         return null;
      end if;
   end Counter_Lookup_Callback_Proxy;

   procedure Set_Counter_Function (callback : Counter_Lookup_Callback) is
      procedure Invoke ( callback : C_Counter_Lookup_Callback);
      pragma Import (CPP, Invoke, "_ZN2v82V818SetCounterFunctionEPFPiPKcE");
   begin
      if callback /= null then
         Current_Counter_Lookup_Callback := callback;
         Invoke (Counter_Lookup_Callback_Proxy'Access);
      else
         Current_Counter_Lookup_Callback := null;
         Invoke (null);
      end if;
   end Set_Counter_Function;

   ---------------------------
   -- Set_Flags_From_String --
   ---------------------------

   procedure Set_Flags_From_String (str : String) is
      procedure Invoke (str : String; length : int);
      pragma Import (CPP, Invoke, "_ZN2v82V818SetFlagsFromStringEPKci");
   begin
      Invoke(str, str'Length);
   end Set_Flags_From_String;
   pragma Inline (Set_Flags_From_String);


   -----------------------------
   -- Add_Implicit_References --
   -----------------------------

   procedure Add_Implicit_References
     (persist_parent   : v8.CLass_Object.Pointer;
      persist_children : v8.Class_Value.Value_Array)
   is
      procedure Invoke
        (persist_parent   : v8.CLass_Object.Pointer;
         persist_children : v8.Class_Value.Value_Array;
         children_count   : C.size_t);
      pragma Import (CPP, Invoke, "_ZN2v82V821AddImplicitReferencesENS_10PersistentINS_6ObjectEEEPNS1_INS_5ValueEEEj");
   begin
      Invoke (persist_parent, persist_children, persist_children'Length);
   end Add_Implicit_References;
   pragma Inline (Add_Implicit_References);

   ----------------------
   -- Add_Object_Group --
   ----------------------

   procedure Add_Object_Group
     (objects : v8.Class_Object.Object_Array;
      info    : v8.Class_Retained_Object_Info.Pointer := null)
   is
      procedure Invoke
        (objects : v8.Class_Object.Object_Array;
         length  : size_t;
         info    : v8.Class_Retained_Object_Info.Pointer);
      pragma Import (CPP, Invoke, "_ZN2v82V814AddObjectGroupEPNS_10PersistentINS_5ValueEEEjPNS_18RetainedObjectInfoE");
   begin
      Invoke (objects, objects'Length, info);
   end Add_Object_Group;


   -------------------------
   -- Terminate_Execution --
   -------------------------

   procedure Terminate_Execution (thread_id : int) is
      procedure Invoke (thread_id : int);
      pragma Import (CPP, Invoke, "_ZN2v82V818TerminateExecutionEi");
   begin
      Invoke(thread_id);
   end Terminate_Execution;
   pragma Inline (Terminate_Execution);

   procedure Terminate_Execution (the_isolate : v8.Class_Isolate.Pointer := null) is
      procedure Invoke (the_isolate : v8.Class_Isolate.Pointer);
      pragma Import (CPP, Invoke, "_ZN2v82V818TerminateExecutionEPNS_7IsolateE");
   begin
      Invoke (the_isolate);
   end Terminate_Execution;
   pragma Inline(Terminate_Execution);

end v8.Class_V8;
